package com.foreveross.crawl.adapter.sub.impl20140402.v3.qunar;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.hyperic.sigar.pager.PageFetchException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.foreveross.crawl.adapter.PlaneInfoEntityBuilder;
import com.foreveross.crawl.adapter.sub.impl20140402.v3.QunarAdapter;
import com.foreveross.crawl.common.PlaneInfoCommon;
import com.foreveross.crawl.domain.airfreight.AbstractPlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.TransitEntity;
import com.foreveross.crawl.domain.airfreight.doub.DoublePlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnDoublePlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnTransitEntity;
import com.foreveross.taskservice.common.bean.TaskModel;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlRadioButtonInput;

public class QunarInterRound {
	protected Log logger = LogFactory.getLog(getClass());
	private TaskModel taskQueue;
	private QunarAdapter adapter;
	
	// 往返获取代理商开关（true 获取代理信息，false不获取代理信息）
		private static boolean returnFlag = false;
	
	//是否只抓取直飞
	private static final boolean isOnlyFetchDirect = true;
	
	
	private static final int fethmoretrysize=3;
	
	public QunarInterRound(QunarAdapter adapter,TaskModel taskQueue){
		this.adapter = adapter;
		this.taskQueue = taskQueue;
	}
	
	public  List<Object> fetch() throws Exception{
			return  parseInterRound(fetchInterRound());
		//return newParseInterRound(newFetchInterRound());//webclient
	}
	
	
	/**
	 * 去哪儿国际往返  用com.gargoylesoftware.htmlunit.WebClient 抓取
	 * @return
	 * @throws Exception
	 */
	private Object newFetchInterRound()throws Exception {
		String url="http://flight.qunar.com/";
		String page;
		HtmlPage queryPage;
		HtmlForm form;
		WebClient clent=null;
		try {
			clent=adapter.getWebClient();
			clent.getOptions().setCssEnabled(false);
			clent.getOptions().setTimeout(5*1000);
			
			queryPage=clent.getPage(url);
			//等待两秒钟载入数据
			Thread.sleep(1000*2);
			form=(HtmlForm) queryPage.getElementById("dfsForm");
			HtmlRadioButtonInput searchType=form.getInputByValue("RoundTripFlight");
			searchType.click();
			
			HtmlInput fromCity=form.getInputByName("fromCity");
			fromCity.setValueAttribute(getCity(this.taskQueue.getFromCityName()));
			
			HtmlInput toCity=form.getInputByName("toCity");
			toCity.setValueAttribute(getCity(this.taskQueue.getToCityName()));
			
			HtmlInput fromDate=form.getInputByName("fromDate");
			fromDate.setValueAttribute(taskQueue.getFlightDate());
			
			HtmlInput toDate=form.getInputByName("toDate");
			toDate.setValueAttribute(taskQueue.getReturnGrabDate());
			
			Iterable<HtmlElement> list =form.getElementsByTagName("button");
			HtmlElement button=list.iterator().next();
			
			queryPage=button.click();
			
			//清空数据
			searchType=null;
			fromCity=null;
			toCity=null;
			fromDate=null;
			toDate=null;
			list=null;
			button=null;
			
			Thread.sleep(1000*10);
			
			HtmlAnchor an=queryPage.getAnchorByText("投资者关系");
			an.setAttribute("name", "123123");
			an.setAttribute("href", "#123123");
			an.setTextContent("123");
			an.removeAttribute("target");
			an.removeAttribute("rel");
			queryPage=an.click();
			
			an=null;
			Thread.sleep(1000*15);
			
			HtmlElement div=queryPage.getHtmlElementById("lp_hdivResultPanel");
			List<HtmlElement> ps=div.getHtmlElementsByTagName("p");
			for(HtmlElement htmlElement:ps){
				if("ico_sp_zhuan".equals(htmlElement.getAttribute("class"))){
					htmlElement.mouseOver();
				}
			}
			div=null;
			ps=null;
			
			page=queryPage.asXml();
			adapter.appendPageContents(page);//设置源网页数据
			adapter.setLenghtCount(page.length());
			return page;
		}finally{
			queryPage=null;
			form=null;
			if(null!=clent)
				clent.closeAllWindows();
		}
		
	}
	
	/**
	 * 新的解析方法 ，解析页面
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	private List<Object> newParseInterRound(Object obj) throws Exception {
		List<AbstractPlaneInfoEntity> result = new ArrayList<AbstractPlaneInfoEntity>();
		Document doc;
		Element divElem;
		Element from;
		Elements flights;
		try{
			doc=Jsoup.parse(obj.toString());
			divElem=doc.getElementById("lp_hdivResultPanel");
			flights=divElem.getElementsByClass("avt_column");
			for(Element flight:flights){
				try {
					from=flight.getElementsByClass("avt_column_1st").get(0);
					DoublePlaneInfoEntity planeInfo=this.transformDiv(from);
					
					ReturnDoublePlaneInfoEntity returnplaneInfo=this.transReturnformDiv(flight.getElementsByClass("avt_column_2nd").get(0));
					
					
					Element prc=flight.getElementsByClass("prc").get(0);
					String price=adapter.changToPrice(prc);
					prc=null;
					
					String taxePrice=null;
					Elements a_inc_tax=flight.getElementsByClass("a_inc_tax");
					if(null!=a_inc_tax){
						Elements tax=a_inc_tax.get(0).getElementsByClass("prc_wp");
						if(null!=tax && !tax.isEmpty()){
							taxePrice=tax.get(0).text();
							tax=null;
						}
					
						a_inc_tax=null;
					}
					planeInfo.setTotalLowestPrice(null==price?null:Double.parseDouble(price));
					planeInfo.setTotalLowestTaxesPrice(null==taxePrice?null:Double.parseDouble(taxePrice));
					if(null!=planeInfo.getTotalLowestPrice() && null!=planeInfo.getTotalLowestTaxesPrice())
						planeInfo.setSumLowestPrice(planeInfo.getTotalLowestPrice()+planeInfo.getTotalLowestTaxesPrice());
					
					returnplaneInfo.setTotalLowestPrice(planeInfo.getTotalLowestPrice());
					returnplaneInfo.setTotalLowestTaxesPrice(planeInfo.getTotalLowestTaxesPrice());
					returnplaneInfo.setSumLowestPrice(planeInfo.getSumLowestPrice());
					planeInfo.getReturnPlaneInfos().add(returnplaneInfo);
					result.add(planeInfo);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			
		}finally{
			doc=null;
			divElem=null;
			from=null;
			flights=null;
		}
		return Arrays.asList(result.toArray());
	}
	

	private DoublePlaneInfoEntity transformDiv(Element from) throws Exception {
		
		String start=from.getElementsByClass("a_tm_dep").get(0).text();
		Date startTime=PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), start);
		Date endTime=null;
		String end=from.getElementsByClass("a_tm_arv").get(0).text();
		if(end.indexOf(" ")>0){
			String[] ends=end.split(" ");
			endTime=PlaneInfoEntityBuilder.getFlightTime(ends[ends.length-1], ends[0]);
		}else{
			endTime=PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), end);
		}
		
		Long flightDuration=null;
		Elements a_pty_mint=from.getElementsByClass("a_pty_mint");
		if(null!=a_pty_mint && a_pty_mint.size()>0){
			String time=a_pty_mint.get(0).text();
			flightDuration=PlaneInfoCommon.getLongtime(time);
			a_pty_mint=null;
		}
		Elements ico_sp_zhifei=from.getElementsByClass("ico_sp_zhifei");
		if(null!=ico_sp_zhifei && ico_sp_zhifei.size()>0){
			//直飞
			String carrierName =from.getElementsByClass("a_name").get(0).text();
			String[] strs=from.getElementsByClass("a_name").get(1).text().split(" ");
			DoublePlaneInfoEntity plane = PlaneInfoEntityBuilder
					.buildPlaneInfo(taskQueue, strs[0].substring(0, 2),
							carrierName, carrierName, null, null, strs[0],
							null, null, null, strs[1], null, null, null,
							null, DoublePlaneInfoEntity.class);
			plane.setStartTime(startTime);
			plane.setEndTime(endTime);
			plane.setFlightDuration(flightDuration);
			return plane;
		}
		
		String fromAirPortName=from.getElementsByClass("a_lacal_dep").get(0).text();
		
		String toAirPortName=from.getElementsByClass("a_local_arv").get(0).text();
		
		ArrayList<TransitEntity> transits = new ArrayList<TransitEntity>();
		
		Elements c1=from.getElementsByClass("c1");
		for(Element e:c1){
			String carrierName =e.getElementsByClass("a_name").get(0).text();
			Elements strongs=e.getElementsByTag("strong");
			for(Element f:strongs){
				String[] str=f.text().split(" ");
				String flightNo=str[0];
				String flightType=str[1];
				TransitEntity traint=new TransitEntity();
				traint.setCarrierName(carrierName);
				traint.setCarrierFullName(carrierName);
				traint.setFlightNo(flightNo);
				traint.setFlightType(flightType);
				transits.add(traint);
			}
		}
		if(transits!=null){
			transits.get(0).setFromAirPortName(fromAirPortName);
			transits.get(0).setStartTime(startTime);
			transits.get(transits.size()-1).setToAirPortName(toAirPortName);
			transits.get(transits.size()-1).setEndTime(endTime);
		}
		
		Elements trains=from.getElementsByClass("trains01");
		String flightDate=taskQueue.getFlightDate();
		if(null!=trains && trains.size()>0){
			for(int i=0;i<trains.size();i++){
				Element trains01=trains.get(i).getElementsByTag("p").get(0);
				String[] strs=trains01.text().split(" ");
				String traintPortName=strs[1];
				String[] times=strs[3].split("-");
				String stayTimeStr=strs[7];
				
				Date arriveTime=PlaneInfoEntityBuilder.getFlightTime(flightDate, times[0]);
				Elements i_1day=trains01.getElementsByClass("i_1day");
				if(null!=i_1day)
					flightDate=this.addOneDay(flightDate,1);
				Elements i_2day=trains01.getElementsByClass("i_2day");
				if(null!=i_2day)
					flightDate=this.addOneDay(flightDate,2);
				Date depTime=PlaneInfoEntityBuilder.getFlightTime(flightDate, times[1]);
				
				Long stayTime=PlaneInfoCommon.getStayTime(stayTimeStr);
				
				transits.get(i).setEndTime(arriveTime);
				transits.get(i).setToAirPortName(traintPortName);
				transits.get(i).setStayTime(stayTime);
				
				transits.get(i+1).setStartTime(depTime);
				transits.get(i+1).setToAirPortName(traintPortName);
			}
		}
		TransitEntity traint=transits.get(0);
		DoublePlaneInfoEntity plane = PlaneInfoEntityBuilder
				.buildPlaneInfo(taskQueue, traint.getFlightNo().substring(0, 2),
						traint.getCarrierName(), traint.getCarrierName(), null, null, traint.getFlightNo(),
						null, null, null, traint.getFlightType(), null, null, null,
						null, DoublePlaneInfoEntity.class);
		plane.setStartTime(startTime);
		plane.setEndTime(endTime);
		plane.setFlightDuration(flightDuration);
		plane.setTransits(transits);
		return plane;
	}
	
	private ReturnDoublePlaneInfoEntity transReturnformDiv(Element from) throws Exception {
		
		String start=from.getElementsByClass("a_tm_dep").get(0).text();
		Date startTime=PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), start);
		Date endTime=null;
		String end=from.getElementsByClass("a_tm_arv").get(0).text();
		if(end.indexOf(" ")>0){
			String[] ends=end.split(" ");
			endTime=PlaneInfoEntityBuilder.getFlightTime(ends[ends.length-1], ends[0]);
		}else{
			PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), end);
		}
		
		Long flightDuration=null;
		Elements a_pty_mint=from.getElementsByClass("a_pty_mint");
		if(null!=a_pty_mint && a_pty_mint.size()>0){
			String time=a_pty_mint.get(0).text();
			flightDuration=PlaneInfoCommon.getLongtime(time);
			a_pty_mint=null;
		}
		Elements ico_sp_zhifei=from.getElementsByClass("ico_sp_zhifei");
		if(null!=ico_sp_zhifei && ico_sp_zhifei.size()>0){
			//直飞
			String carrierName =from.getElementsByClass("a_name").get(0).text();
			String[] strs=from.getElementsByClass("a_name").get(1).text().split(" ");
			ReturnDoublePlaneInfoEntity plane = PlaneInfoEntityBuilder
					.buildPlaneInfo(taskQueue, strs[0].substring(0, 2),
							carrierName, carrierName, null, null, strs[0],
							null, null, null, strs[1], null, null, null,
							null, ReturnDoublePlaneInfoEntity.class);
			plane.setStartTime(startTime);
			plane.setEndTime(endTime);
			plane.setFlightDuration(flightDuration);
			return plane;
		}
		
		String fromAirPortName=from.getElementsByClass("a_lacal_dep").get(0).text();
		
		String toAirPortName=from.getElementsByClass("a_local_arv").get(0).text();
		
		ArrayList<ReturnTransitEntity> transits = new ArrayList<ReturnTransitEntity>();
		
		Elements c1=from.getElementsByClass("c1");
		for(Element e:c1){
			String carrierName =e.getElementsByClass("a_name").get(0).text();
			Elements strongs=e.getElementsByTag("strong");
			for(Element f:strongs){
				String[] str=f.text().split(" ");
				String flightNo=str[0];
				String flightType=str[1];
				ReturnTransitEntity traint=new ReturnTransitEntity();
				traint.setCarrierName(carrierName);
				traint.setCarrierFullName(carrierName);
				traint.setFlightNo(flightNo);
				traint.setFlightType(flightType);
				transits.add(traint);
			}
		}
		if(transits!=null){
			transits.get(0).setFromAirPortName(fromAirPortName);
			transits.get(0).setStartTime(startTime);
			transits.get(transits.size()-1).setToAirPortName(toAirPortName);
			transits.get(transits.size()-1).setEndTime(endTime);
		}
		
		Elements trains=from.getElementsByClass("trains01");
		String returnFlightDate=taskQueue.getReturnGrabDate();
		if(null!=trains && trains.size()>0){
			for(int i=0;i<trains.size();i++){
				Element trains01=trains.get(i).getElementsByTag("p").get(0);
				String[] strs=trains01.text().split(" ");
				String traintPortName=strs[1];
				String[] times=strs[3].split("-");
				String stayTimeStr=strs[7];
				
				Date arriveTime=PlaneInfoEntityBuilder.getFlightTime(returnFlightDate, times[0]);
				Elements i_1day=trains01.getElementsByClass("i_1day");
				if(null!=i_1day)
					returnFlightDate=this.addOneDay(returnFlightDate,1);
				Elements i_2day=trains01.getElementsByClass("i_2day");
				if(null!=i_2day)
					returnFlightDate=this.addOneDay(returnFlightDate,2);
				Date depTime=PlaneInfoEntityBuilder.getFlightTime(returnFlightDate, times[1]);
				
				Long stayTime=PlaneInfoCommon.getStayTime(stayTimeStr);
				
				transits.get(i).setEndTime(arriveTime);
				transits.get(i).setToAirPortName(traintPortName);
				transits.get(i).setStayTime(stayTime);
				
				transits.get(i+1).setStartTime(depTime);
				transits.get(i+1).setToAirPortName(traintPortName);
			}
		}
		ReturnTransitEntity traint=transits.get(0);
		ReturnDoublePlaneInfoEntity plane = PlaneInfoEntityBuilder
				.buildPlaneInfo(taskQueue, traint.getFlightNo().substring(0, 2),
						traint.getCarrierName(), traint.getCarrierName(), null, null, traint.getFlightNo(),
						null, null, null, traint.getFlightType(), null, null, null,
						null, ReturnDoublePlaneInfoEntity.class);
		plane.setStartTime(startTime);
		plane.setEndTime(endTime);
		plane.setFlightDuration(flightDuration);
		plane.setReturnTransits(transits);
		return plane;
	}
	

	private String addOneDay(String flightDate,int days) throws ParseException {
		if(null==flightDate)
			return null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date d=sdf.parse(flightDate);
		Calendar c=Calendar.getInstance();
		c.setTime(d);
		c.add(Calendar.DAY_OF_MONTH, days);
		return sdf.format(c.getTime());
	}

	private Object fetchInterRound() throws Exception {
		HttpClient h = null;
		HttpGet g = null;
		Map<String, String> p = new HashMap<String, String>();
		String page = null;
		JSONObject j;
		try {
			h = adapter.getHttpClient();
			
			int token=(int) (Math.random()*100000);
			p.put("_token", token+"");
//			p.put("_token", "68571");
//			p.put("from", "fi_ont_search");
			p.put("from", "from_rtrip_qiri");
//			if(isOnlyFetchDirect){
//				p.put("ftransfertime", "0");
//			}
			p.put("fromCity", getCity(taskQueue.getFromCityName()));
			p.put("toCity", getCity(taskQueue.getToCityName()));
			p.put("fromDate", taskQueue.getFlightDate());
			p.put("toDate", taskQueue.getReturnGrabDate());
			p.put("http://www.travelco.com/searchDepartureAirport", getCity(taskQueue.getFromCityName()));
			p.put("http://www.travelco.com/searchArrivalAirport", getCity(taskQueue.getToCityName()));
			p.put("http://www.travelco.com/searchDepartureTime", taskQueue.getFlightDate());
			p.put("http://www.travelco.com/searchReturnTime", taskQueue.getReturnGrabDate());
			p.put("isInter", "true");
			p.put("locale", "zh");
			p.put("mergeFlag", "0");
			p.put("nextNDays", "0");
			p.put("op", "1");
			p.put("prePay", "true");
			p.put("reset", "true");
			p.put("searchLangs", "zh");
			p.put("searchType", "RoundTripFlight");
			p.put("version", "thunder");
			p.put("www", "true"); // 这个会影响返回的数据结构，还有返回异常性
			p.put("xd", "f" + System.currentTimeMillis());
//			p.put("wyf", "");
			g = adapter.getBaseGet("http://flight.qunar.com/twelli/longwell", p);
//			adapter.setCookiesToMethodByPing("http://flight.qunar.com/", h, g);
//			adapter.setCookiesToMethodByPing("http://flight.qunar.com/site/interroundtrip_compare.htm?fromCity="+getCity(taskQueue.getFromCityName())+"&toCity="+getCity(taskQueue.getToCityName())+"&fromDate="+taskQueue.getFlightDate()+"&toDate="+taskQueue.getReturnGrabDate()+"&fromCode="+taskQueue.getFromCity()+"&toCode="+taskQueue.getToCity()+"&from=fi_ont_search&lowestPrice=null&isInter="+(taskQueue.getIsInternational()==1), h, g);
			page = adapter.excuteRequest(h, g, true);
			j = JSONObject.fromObject(page.trim().replaceAll("^\\(|\\)$", ""));
			adapter.validateFetch(j);
		} finally {
			page = null;
			if (g != null) {
				g.releaseConnection();
				g = null;
			}
			h = null;
		}
		
		return j;
	}
	
	private List<Object> parseInterRound(Object obj) throws Exception {
		List<AbstractPlaneInfoEntity> result = new ArrayList<AbstractPlaneInfoEntity>();
		JSONObject j;
		JSONObject compInfo;// 公司对应关系json
		JSONObject flightInfo;// 航班组合对应关系
		JSONObject packagePriceInfo;
		JSONArray combinePriceInfo;
		JSONObject airportInfo;
		Map<String, String> depAryMap = new HashMap<String, String>();

		String key;
		Iterator<Entry<String, String>> it;
		Entry<String, String> en;
		String serverIP;
		String queryID;
		JSONObject transferInfo;
		try {
			j = (JSONObject) obj;
			if(null!=j.getJSONObject("rt_data") || !j.getJSONObject("rt_data").isEmpty()){
				JSONObject rt_data = j.getJSONObject("rt_data");
				packagePriceInfo = rt_data.getJSONObject("packagePriceInfo");
				if(null==packagePriceInfo || packagePriceInfo.isEmpty())
				//没有打包价就抓取新的数据
				for(int i=0;i<fethmoretrysize;i++){
					j=(JSONObject) fetchInterRound();
					packagePriceInfo=j.getJSONObject("rt_data").getJSONObject("packagePriceInfo");
					if(null!=packagePriceInfo && !packagePriceInfo.isEmpty()){
						break;
					}
				}
			}
			
			
			JSONObject rt_data = j.getJSONObject("rt_data");
			compInfo =rt_data.getJSONObject("carrierInfo");// 航空公司
			flightInfo = rt_data.getJSONObject("flightInfo");// 去程或者回程的信息key:1TR2109/TR2986 0MU5740/MU741
			packagePriceInfo = rt_data.getJSONObject("packagePriceInfo");
			combinePriceInfo = rt_data.getJSONArray("combinePriceInfo");
			transferInfo = rt_data.getJSONObject("transferInfo");
			airportInfo = j.getJSONObject("airportInfo");
			serverIP = j.getString("serverIP");
			queryID = j.getString("queryID");
	
			// 简易取得航班信息
			// 0CX1234/CX1111|CA1234/CA4567/CA111
			// 0CX1234/CX113/CZ445|CA1234/CA4567/CA111
			// 虽然起飞的第一转相同，但是第二转不同，所以识别为两个entity,当|前完全一致的时候，认为是同去不同回

			for (Object o : packagePriceInfo.keySet()) {
				key = o.toString();
				if (!depAryMap.containsKey(key.split("\\|")[0])) {
					depAryMap.put(key.split("\\|")[0], key.split("\\|")[1]);
				} else {
					depAryMap.put(key.split("\\|")[0], depAryMap.get(key.split("\\|")[0]) + "," + key.split("\\|")[1]);
				}
			}
			
			//这个里面也有航班关系，outPriceInfo的价格和retPriceInfo的价格等于总价，但是暂时找不到他们的关系，添加航班的时候暂忽略
			for (Object o : combinePriceInfo) {
				key = JSONObject.fromObject(o).getString("key");
				if (!depAryMap.containsKey(key.split("\\|")[0])) {
					depAryMap.put(key.split("\\|")[0], key.split("\\|")[1]);
				} else {
					depAryMap.put(key.split("\\|")[0], depAryMap.get(key.split("\\|")[0]) + "," + key.split("\\|")[1]);
				}
			}
			if (j.get("inter_filters") != null && j.getJSONObject("inter_filters").get("fcarrier") != null) {// 这个里面有最低价格的航班
				JSONObject fcarrier = j.getJSONObject("inter_filters").getJSONObject("fcarrier");
				for (Object o1 : fcarrier.values()) {
					for (Object o2 : ((JSONObject) o1).values()) {
						JSONObject f = (JSONObject) o2;
						String f1 = f.getString("key").split("\\|")[0];
						String f2 = f.getString("key").split("\\|")[1];
						if (!depAryMap.containsKey(f1)) {
							depAryMap.put(f1, f2);
						} else if (depAryMap.get(f1).indexOf(f2) == -1) {
							depAryMap.put(f1, depAryMap.get(f1) + "," + f2);
						}
					}
				}
			}

			// 得到航班组合之后，开始切割数据
			it = depAryMap.entrySet().iterator();
			while (it.hasNext()) {
				JSONObject if1;
				JSONObject if2;
				DoublePlaneInfoEntity dPlaneInfoEntity;// 往返实体
				ReturnDoublePlaneInfoEntity rPlaneInfoEntity;// 回程实体
				en = it.next();
				if1 = flightInfo.getJSONObject(en.getKey());
				List<PriceCollect> prices = new ArrayList<PriceCollect>();
				try {
					dPlaneInfoEntity = (DoublePlaneInfoEntity) PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, if1.getString("ca"), compInfo.getJSONObject(if1.getString("ca")).getString("zh"),
							compInfo.getJSONObject(if1.getString("ca")).getString("full"), if1.getString("dt"), if1.getString("at") + "+" + (if1.getInt("cd") < 0 ? 0 : if1.getInt("cd")), 
							en.getKey().replaceAll("^\\d", "").replaceAll("/.*", ""),// 航班号是截取第一个
							null, null, null, if1.getString("pt"));

					try {
						dPlaneInfoEntity.setFlightDuration(adapter.getLong(if1.getLong("dur")));
					} catch (Exception e) {
					}
					// 经停
					adapter.addStopover(dPlaneInfoEntity, if1, en.getKey());

					if (en.getKey().indexOf("/") != -1) {// 去中转
						TransitEntity t;
						String[] arr = en.getKey().split("/");
						JSONArray tran = null;
						try {
							tran = transferInfo.getJSONArray(en.getKey().replaceAll("^0|^1", "").replaceAll("/[01]", "/"));
						} catch (Exception e) {
						}
						for (int i = 0; i < arr.length; i++) {
							t = new TransitEntity();
							String no = arr[i];
							t.setFlightNo(no.replaceAll("^0|^1", ""));
							// 添加中转信息
							if (tran != null) {
								try {
									JSONObject lastObj = null;
									JSONObject thisObj = null;
									if (i == 0) {
										thisObj = tran.getJSONObject(i);
										t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), if1.getString("dt")));
										t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), thisObj.getString("at") + "+" + (thisObj.getInt("cd") < 0 ? 0 : thisObj.getInt("cd"))));
										t.setFromAirPort(if1.getString("da"));
										try {
											t.setFromAirPortName(airportInfo.getJSONObject("ret").getJSONObject(if1.getString("da")).getString("ab"));
										} catch (Exception e) {
											t.setFromAirPortName(airportInfo.getJSONObject("out").getJSONObject(if1.getString("da")).getString("ab"));
										}
										t.setToAirPortName(thisObj.getJSONArray("ta").getString(0));
										t.setStayTime(adapter.getLong(thisObj.getLong("dur")));
									} else if (i == arr.length - 1) {
										lastObj = tran.getJSONObject(i - 1);
										t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), lastObj.getString("dt") + "+" + (lastObj.getInt("cd") < 0 ? 0 : lastObj.getInt("cd"))));
										t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), if1.getString("at") + "+" + (if1.getInt("cd") < 0 ? 0 : if1.getInt("cd"))));
										t.setFromAirPortName(lastObj.getJSONArray("ta").getString(1));
										t.setToAirPort(if1.getString("aa"));
										t.setToAirPortName(airportInfo.getJSONObject(if1.getString("aa")).getString("ab"));
										try {
											t.setToAirPortName(airportInfo.getJSONObject("ret").getJSONObject(if1.getString("aa")).getString("ab"));
										} catch (Exception e) {
											t.setToAirPortName(airportInfo.getJSONObject("out").getJSONObject(if1.getString("aa")).getString("ab"));
										}
									} else {
										lastObj = tran.getJSONObject(i - 1);
										thisObj = tran.getJSONObject(i);
										t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), lastObj.getString("dt") + "+" + (lastObj.getInt("cd") < 0 ? 0 : lastObj.getInt("cd"))));
										t.setToAirPortName(lastObj.getJSONArray("ta").getString(1));
										t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), thisObj.getString("at") + "+" + (thisObj.getInt("cd") < 0 ? 0 : thisObj.getInt("cd"))));
										t.setToAirPortName(thisObj.getJSONArray("ta").getString(0));
										t.setStayTime(adapter.getLong(thisObj.getLong("dur")));
									}
								} catch (Exception e) {
								}
							}
							dPlaneInfoEntity.getTransits().add(t);
						}
					}
					
					for (String rNos : en.getValue().split(",")) {// 切割回程航班
						// 组合分别找到出发和结束时间
						if2 = flightInfo.getJSONObject(rNos);
						// 回程如果也是中转，则用去的第一个构建ReturnDoublePlaneInfoEntity
						rPlaneInfoEntity = PlaneInfoEntityBuilder.getReturnTrip(taskQueue, if2.getString("ca"), compInfo.getJSONObject(if2.getString("ca")).getString("zh"), compInfo.getJSONObject(if2.getString("ca")).getString("full"),
								if2.getString("dt"), if2.getString("at") + "+" + (if2.getInt("cd") < 0 ? 0 : if2.getInt("cd")), 
								rNos.replaceAll("^\\d", "").replaceAll("/.*", ""), null, null, null, if2.getString("pt"));
						try{
							rPlaneInfoEntity.setFlightDuration(adapter.getLong(if2.getLong("dur")));
						}catch(Exception e){
						}
						PriceCollect priceCollect = getPriceCollect(rt_data, en.getKey()+"|"+rNos);
						if(priceCollect == null ){
							//没获取到价格信息
							continue;
						}else{
							rPlaneInfoEntity.setTotalHighestTaxesPrice(priceCollect.getTaxesPrice());
							rPlaneInfoEntity.setTotalLowestTaxesPrice(priceCollect.getTaxesPrice());
							rPlaneInfoEntity.setSumHighestPrice(priceCollect.getOriginalPrice());
							rPlaneInfoEntity.setSumLowestPrice(priceCollect.getOriginalPrice());
							rPlaneInfoEntity.setTotalLowestPrice(priceCollect.getPrice());
							rPlaneInfoEntity.setTotalHighestPrice(priceCollect.getPrice());
							prices.add(priceCollect);
						}

						adapter.setPagePriceCabin(rPlaneInfoEntity);

						// 经停
						adapter.addStopover(rPlaneInfoEntity, if2, rNos);
						if (rNos.indexOf("/") != -1) {// 回中转
							String[] arr = rNos.split("/");
							JSONArray tran = null;
							try {
								tran = transferInfo.getJSONArray(rNos.replaceAll("^0|^1", "").replaceAll("/[01]", "/"));
							} catch (Exception e) {
							}
							ReturnTransitEntity t;
							for (int i = 0; i < arr.length; i++) {
								String no = arr[i];
								t = new ReturnTransitEntity();
								t.setFlightNo(no.replaceAll("^0|^1", ""));
								// 添加回程中转信息
								if (tran != null) {
									try {
										JSONObject lastObj = null;
										JSONObject thisObj = null;
										if (i == 0) {
											thisObj = tran.getJSONObject(i);
											t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), if2.getString("dt")));
											t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), thisObj.getString("at") + "+" + (thisObj.getInt("cd") < 0 ? 0 : thisObj.getInt("cd"))));
											t.setFromAirPort(if2.getString("da"));
											t.setFromAirPortName(airportInfo.getJSONObject(if2.getString("da")).getString("ab"));
											try {
												t.setFromAirPortName(airportInfo.getJSONObject("ret").getJSONObject(if2.getString("da")).getString("ab"));
											} catch (Exception e) {
												t.setFromAirPortName(airportInfo.getJSONObject("ret").getJSONObject("out").getJSONObject(if2.getString("da")).getString("ab"));
											}
											t.setToAirPortName(thisObj.getJSONArray("ta").getString(0));
											t.setStayTime(adapter.getLong(thisObj.getLong("dur")));
										} else if (i == arr.length - 1) {
											lastObj = tran.getJSONObject(i - 1);
											t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), lastObj.getString("dt") + "+" + (lastObj.getInt("cd") < 0 ? 0 : lastObj.getInt("cd"))));
											t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), if2.getString("at") + "+" + (if2.getInt("cd") < 0 ? 0 : if2.getInt("cd"))));
											t.setFromAirPortName(lastObj.getJSONArray("ta").getString(1));
											t.setToAirPort(if2.getString("aa"));
											t.setToAirPortName(airportInfo.getJSONObject(if2.getString("aa")).getString("ab"));
											try {
												t.setToAirPortName(airportInfo.getJSONObject("ret").getJSONObject(if2.getString("aa")).getString("ab"));
											} catch (Exception e) {
												t.setToAirPortName(airportInfo.getJSONObject("out").getJSONObject(if2.getString("aa")).getString("ab"));
											}
										} else {
											lastObj = tran.getJSONObject(i - 1);
											thisObj = tran.getJSONObject(i);
											t.setStartTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), lastObj.getString("dt") + "+" + (lastObj.getInt("cd") < 0 ? 0 : lastObj.getInt("cd"))));
											t.setToAirPortName(lastObj.getJSONArray("ta").getString(1));
											t.setEndTime(PlaneInfoEntityBuilder.getFlightTime(taskQueue.getFlightDate(), thisObj.getString("at") + "+" + (thisObj.getInt("cd") < 0 ? 0 : thisObj.getInt("cd"))));
											t.setToAirPortName(thisObj.getJSONArray("ta").getString(0));
											t.setStayTime(adapter.getLong(thisObj.getLong("dur")));
										}
									} catch (Exception e) {
									}
								}
								rPlaneInfoEntity.getReturnTransits().add(t);
							}

						}
						dPlaneInfoEntity.getReturnPlaneInfos().add(rPlaneInfoEntity);
					}

					if (returnFlag) {
						//找出代理商
						adapter.setDoublePlaneInfoEntityMoreAgent(dPlaneInfoEntity, prices, serverIP, queryID);
					}

					if (!prices.isEmpty()) {
						PriceCollect.buildPrice(dPlaneInfoEntity, prices);
					}
					
					result.add(dPlaneInfoEntity);
					/* showDirect(dPlaneInfoEntity); */
				} catch (Exception e) {
					logger.error(String.format("[%s]解析[%s] [%s]-[%s] [%s]-[%s] 详情[%s] 错误[%s]", taskQueue.getGrabChannel(), adapter.getRouteType().getName(), taskQueue.getFromCity(), taskQueue.getToCity(), taskQueue.getFlightDate(),
							taskQueue.getReturnGrabDate(), en.toString(), e));
				} finally {
					if1 = null;
					if2 = null;
					dPlaneInfoEntity = null;
				}

			}
			
		} finally {
			j = null;
			compInfo = null;// 公司对应关系json
			flightInfo = null;// 航班组合对应关系
			packagePriceInfo = null;
			depAryMap = null;
			key = null;
			it = null;
			en = null;
		}
		PlaneInfoCommon.removeNoPrice(result);
		return Arrays.asList(result.toArray());
	}
	


	/**
	 *发现去哪儿网rt_data有好几个对象有价格信息(packagePriceInfo,raInfo,combinePriceInfo)
	 * @param rt_data 往返信息对象
	 * @param key 往返航班号组合 例f1/f2|f3/f4
	 * @return
	 */
	private PriceCollect getPriceCollect(JSONObject rt_data,String key){
		if(rt_data == null || key == null){
			return null;
		}
		JSONObject packagePriceInfo = rt_data.getJSONObject("packagePriceInfo");
		JSONObject info = packagePriceInfo.getJSONObject(key);
		if(!isJSONObjectEmpty(info)){
			Double pr = info.getDouble("lowpr");
			Double tax = info.getDouble("tax");
			return new PriceCollect(tax, pr, pr + tax);
		}
		
		JSONArray combinePriceInfo = rt_data.getJSONArray("combinePriceInfo");
		for(Object o : combinePriceInfo){
			JSONObject priceInfo = JSONObject.fromObject(o);
			if(key.equals(priceInfo.getString("key"))){
				Double pr = priceInfo.getDouble("lowpr");
				Double tax = priceInfo.getDouble("tax");
				return new PriceCollect(tax, pr, pr + tax);
			}
		}
		
		JSONObject raInfo = rt_data.getJSONObject("raInfo");
		Object priceObj = raInfo.get(key);
		if(priceObj != null){
			return new PriceCollect(null,raInfo.getDouble(key),null);
		}
		
		//去程航班价格信息
		JSONObject outPriceInfo = rt_data.getJSONObject("outPriceInfo");
		//回程航班价格信息
		JSONObject retPriceInfo = rt_data.getJSONObject("retPriceInfo");
		String[] arr = key.split("\\|");
		//暂时只考虑往返情况
		if(arr.length == 2){
			JSONObject outInfo = outPriceInfo.getJSONObject(arr[0]);
			JSONObject retInfo = retPriceInfo.getJSONObject(arr[1]);
			if(!isJSONObjectEmpty(outInfo) && !isJSONObjectEmpty(retInfo)){
				Double pr = outInfo.getDouble("lowpr") + retInfo.getDouble("lowpr");
				Double tax = retInfo.getDouble("tax") + retInfo.getDouble("tax");
				return new PriceCollect(tax, pr, pr + tax);
			}
		}
		return null;
	}
	
	private boolean isJSONObjectEmpty(JSONObject j) {
		if (j == null || j.isNullObject() || j.isEmpty()) {
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * 替换掉一个城市机场里面具体机场的名字，都是用城市来查的
	 * @param cityName
	 * @return
	 */
	private static String getCity(String cityName){
		return cityName.replaceAll("\\(.*\\)", "").replaceAll("（.*）", "");
	}
	
}
